/**
 * The contents of this file are subject to the license and copyright detailed in the LICENSE and NOTICE files at the root of the source tree and available online at
 * http://www.askosi.org/license.html
 */
package be.destin.skos.core;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Properties;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlValue;
import javax.xml.datatype.XMLGregorianCalendar;

import org.apache.log4j.Logger;
import org.openrdf.model.Literal;
import org.openrdf.model.URI;
import org.openrdf.model.impl.URIImpl;

import be.destin.rdf.changes.Status;
import be.destin.rdf.changes.StatusInterface;
import be.destin.util.Util;

/* An URL in our SKOS model is most often a multilingual URI template.
 *  It is therefore nearer from a multilingual Literal than from a real URI...
 */
public class Url implements Literal, StatusInterface {
	
    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	// the log
    private static Logger log = Logger.getLogger(Url.class);
	private static final URI template_URL_XML_DATATYPE = new URIImpl("xs:string");

	
	private String language;
	private String url;
	private Status status;

	public Url() {
		super();
	}  
 

	public Url(String language, String value) {
		super();
		this.language = language;
		this.url = value;
	}  

	public static Url newValid(String language, String value) {
		if (language == null) language = TermList.anyLanguage;
		if (value == null) return null;
		language = language.trim();
		value = value.trim();
		if (value.length()==0) return null;
		return new Url (language, value);
	}

	public Url getThis() {
		return this;
	}

	public  boolean equals (Object o) {
		if (! (o instanceof Url )) return false;
		if (this == o) return true;
		Url x = (Url) o;
		return ((x.language.equals(this.language)) && (x.url.equals(this.url)));
	}

	/**
	 * @return the key
	 */
	@XmlAttribute
	public String getLang() {
		return this.language;
	}
	/**
	 * @return the value
	 */
	@XmlValue
	public String getValue() {
		if (this.url==null) return null;
		return this.url;
	}
	
	/**
	 * @return the value as an URL
	public URL toURL() {
		try {
			return new URL (this.url);
		} catch (MalformedURLException e) {
			log.error (this.url+" is an invalid URL.");
			return null;
		}
	}
	 */

	/**
	 * @param key the key to set
	 */
	public void setLang(String key) {
		if (key == null) this.language = null;
		else this.language = key.trim();
	}
	/**
	 * @param value the value to set
	public void setURL(URL value) {
		this.url = value.toExternalForm();
	}
	 */
	
	/**
	 * @param value the value to set
	 */
	public void setValue(String value) {
		if (value == null) this.url = null;
		else this.url = value.trim();
	}
	
	public static String getConfigURL(Properties properties, String aProp) {
		String aUrlString = properties.getProperty(aProp);
		return aUrlString;
		/*
		URL resultURL = null;
		if (aUrlString != null && aUrlString.length() > 0) {
			try {
				resultURL = new URL(applicationRoot,aUrlString);

			} catch (MalformedURLException e){
				log.error("Bad "+aProp+" URL: "+aUrlString+", "+e.toString());
			}
		}
		if (resultURL == null) return null;
		return resultURL.toExternalForm();
		*/
	}

	@XmlAttribute(name="status")
	public String getStatus() {
		if (status == null) return null;
		return status.toString();
	}

	public void setStatus(String aStatus) {
		if (aStatus == null || aStatus.isEmpty()) {
			this.status = null;
			return;
		}
		if (aStatus.startsWith("status_")) {
			aStatus = aStatus.substring("status_".length());
		}
		this.status = Status.valueOf(aStatus);
	}

	@XmlTransient
	public Status getCurrentStatus() {
		return status;
	}

	public void setCurrentStatus(Status status) {
		if (status == null) return;
		this.status = status;
	}

	public String toRdfObjectUrl() {
		return "&literallanguage="+this.language+"&literal="+Util.escapeHTMLEntities(this.url);
	}

	public String toJavaScriptParameters() {
		return ",literallanguage:'"+this.language+"',literal:'"+Util.escapeJavaScript(this.url)+"'";
	}

	// overrides Object.hashCode(), implements hashCode()
    @Override
    public int hashCode() {
        return url.hashCode();
    }

    /**
     * Returns the label of the literal.
     */
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder(url.length() * 2);

        sb.append('"');
        sb.append(url);
        sb.append('"');

        if (language != null) {
            sb.append('@');
            sb.append(language);
        }

        return sb.toString();
    }

    public String stringValue() {
        return url;
    }


    @XmlTransient
	public URI getDatatype() {
		// TODO Auto-generated method stub
		return template_URL_XML_DATATYPE;
	}


    @XmlTransient
	public String getLabel() {
		return url;
	}


    @XmlTransient
	public String getLanguage() {
		return language;
	}


	public boolean booleanValue() {
		// TODO Auto-generated method stub
		return false;
	}


	public byte byteValue() {
		// TODO Auto-generated method stub
		return 0;
	}


	public XMLGregorianCalendar calendarValue() {
		// TODO Auto-generated method stub
		return null;
	}


	public BigDecimal decimalValue() {
		// TODO Auto-generated method stub
		return null;
	}


	public double doubleValue() {
		// TODO Auto-generated method stub
		return 0;
	}


	public float floatValue() {
		// TODO Auto-generated method stub
		return 0;
	}

	public int intValue() {
		// TODO Auto-generated method stub
		return 0;
	}


	public BigInteger integerValue() {
		// TODO Auto-generated method stub
		return null;
	}


	public long longValue() {
		// TODO Auto-generated method stub
		return 0;
	}


	public short shortValue() {
		// TODO Auto-generated method stub
		return 0;
	}
}
